/***************************************************************************
 *   Copyright (C) 2006 by Grzegorz Latarowski                             *
 *   g.latarowski@gmail.com                                                *
 *                                                                         *
 *   Project: AutoStop (kodowa nazwa do zmiany)                            *
 *                                                                         *
 ***************************************************************************/
 
 
 

#include "filterdialog.h"






// ===========================================================================
//                            FilterWizardDialog
// ===========================================================================


// ---------------------------- FilterDialog() -------------------------------
FilterWizardDialog::FilterWizardDialog(MainWindow * parent, Qt::WFlags f)
    : QDialog((QWidget *)parent, f)
{
    _parent = parent;
        // ustaw pusty filtr na dzień dobry 
    _filter = new Filter;
    
    _currentRow = 2;
    
    setWindowTitle(QString::fromUtf8("Kryteria filtrowania"));
    
    columnLabel = new QLabel(QString::fromUtf8("Kolumna"));
    value1Label = new QLabel(QString::fromUtf8("Wartość 1"));
    value2Label = new QLabel(QString::fromUtf8("Wartość 2"));
    operatorLabel = new QLabel(QString::fromUtf8("Operator"));
    okPushButton = new QPushButton(QString::fromUtf8("&OK"));
    okPushButton->setDefault(true);
    cancelPushButton = new QPushButton(QString::fromUtf8("&Anuluj"));
    gridLayout = new QGridLayout;
    
    QVBoxLayout *dialogButtonsLayout = new QVBoxLayout;
    dialogButtonsLayout->addWidget(okPushButton);
    dialogButtonsLayout->addWidget(cancelPushButton);
    dialogButtonsLayout->addStretch();
    
    horizontalLine = new QFrame(this);
    horizontalLine->setGeometry(QRect(30, 30, 291, 16));
    horizontalLine->setFrameShape(QFrame::HLine);
    
    gridLayout->addWidget(operatorLabel, 0, 0);
    gridLayout->addWidget(columnLabel, 0, 1);
    gridLayout->addWidget(value1Label, 0, 2);
    gridLayout->addWidget(value2Label, 0, 3);
    gridLayout->addWidget(horizontalLine, 1, 0, 1, 5);
    
    gridLayout->addLayout(dialogButtonsLayout, 2, 4, 2, 1);
    gridLayout->setColumnMinimumWidth(1, 100);
    gridLayout->setColumnMinimumWidth(2, 100);
    gridLayout->setColumnMinimumWidth(3, 100);
    setLayout(gridLayout);
    
    connect(okPushButton, SIGNAL(clicked()), this, SLOT(acceptFilters()));
    connect(cancelPushButton, SIGNAL(clicked()), this, SLOT(reject())); 
    
    createFilterWidgets(0);
}
// ---------------------------------------------------------------------------


// ------------------------ createFilterWidgets() ----------------------------
void FilterWizardDialog::createFilterWidgets(int)
{    
        // filterWidget tworzony nie pierwszy raz
        // trzeba rozłączyć poprzedni sygnał tworzenia
    if(_currentRow != 2) {
        disconnect(operatorComboBoxList.last(), SIGNAL(activated(int)),
                   this, SLOT(createFilterWidgets(int)));
        disconnect(filterWidgetList.last(), SIGNAL(activated(bool)),
                   operatorComboBoxList.last(), SLOT(setEnabled(bool)));
    }
    
    QStringList items;
    items << QString::fromUtf8("I") << QString::fromUtf8("LUB");
    QComboBox *operatorComboBox = new QComboBox;
    operatorComboBox->addItems(items);
    operatorComboBox->setCurrentIndex(-1);
    operatorComboBox->setDisabled(true);
    
    gridLayout->addWidget(operatorComboBox, _currentRow + 1, 0);
    
    FilterWidget *filterWidget = new FilterWidget(_currentRow, this);
    
    connect(operatorComboBox, SIGNAL(activated(int)),
            this, SLOT(createFilterWidgets(int)));
    connect(filterWidget, SIGNAL(activated(bool)),
            operatorComboBox, SLOT(setEnabled(bool)));
    
    operatorComboBoxList.append(operatorComboBox);
    filterWidgetList.append(filterWidget);
    
        // zwiększ licznik wiersza
    _currentRow++;
}
// ---------------------------------------------------------------------------


// ---------------------- acceptFilters() ------------------------------------
void FilterWizardDialog::acceptFilters()
{
    QList<FilterModel *> filterModelList;
        // utwórz nowy filtr w celu wyczyszczenia danych 
    delete _filter;
    _filter = new Filter;
    
    
    // bzdury testowe 
    QStringList icons;
    icons << QString::fromUtf8(":/filter/images/filterIcons/tux.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/aim.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/babelfish.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/bell.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/clanbomber.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/folder_home.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/freebsd.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/hd2-black.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/penguin.png");
    icons << QString::fromUtf8(":/filter/images/filterIcons/services.png");
    static int filterNumber;
    QString text = QString("Filtr nr. %1").arg(filterNumber);
    _filter->setText(text);
    _filter->setIcon(QIcon(icons.at(filterNumber++)));
    
        // dopuki odpalone były widgety do tworzenia filtrów 
    for(int i = 0; i < filterWidgetList.size(); i++) {    
            // jeśli nie aktywny to przerywaj   
        if(!filterWidgetList.at(i)->isActive()) {
            break;
        }
            // odczytaj utworzony filterModel z widgeta
        FilterModel *filterModel = filterWidgetList.at(i)->filterModel();
            // dodaj go do listy
        filterModelList.append(filterModel);
            // jeśli operator jest I to zakończ tworzenie MultiTypeModelu
        if(operatorComboBoxList.at(i)->currentText() == QString::fromUtf8("I")) {
            MultiTypeSortFilterProxyModel *multiTypeSortFilterModel;
            multiTypeSortFilterModel = new MultiTypeSortFilterProxyModel;
            multiTypeSortFilterModel->setPatternModels(filterModelList);
            _filter->addModel(multiTypeSortFilterModel);
                // i utwórz nową listę
            filterModelList.clear();
        }
    } // for()
    
        // na zakończenie utwórz ostatni MultiTypeModel
    MultiTypeSortFilterProxyModel *multiTypeSortFilterModel;
    multiTypeSortFilterModel = new MultiTypeSortFilterProxyModel;
    multiTypeSortFilterModel->setPatternModels(filterModelList);
        // usuń listę z podModelami 
    _filter->addModel(multiTypeSortFilterModel);

//     _parent->setFilter(_filter);
    
        // zapisz utworzony filtr do bazy 
    QByteArray byteArray;
    QBuffer buffer(&byteArray);
    buffer.open(QIODevice::WriteOnly);
    QDataStream out(&buffer);
    out << _filter;
    buffer.close();

    QSqlQuery query;
    query.prepare("INSERT INTO filters (id, filter) VALUES (?, ?)");
    query.bindValue(1, byteArray, QSql::In | QSql::Binary);
    query.exec();
    
    accept();
}
// ---------------------------------------------------------------------------






// ===========================================================================
//                             FilterWidget
// ===========================================================================


// ------------------------ FilterWidget() -----------------------------------
FilterWidget::FilterWidget(int row, FilterWizardDialog *parent, Qt::WFlags f)
    : QWidget((QWidget *)parent, f)
{
    _parent = parent;
    _row = row;
    gridLayout = _parent->getGridLayout();
    
        // zaczytaj nagłówki 
    _header = new QSqlTableModel;
    _header->setTable("header");
    _header->select();
    
        // utwórz combo ze wszystkich nagłówków 
    QComboBox *columnComboBox = new QComboBox;
    for(int i = 0; i < _header->rowCount(); i++) {
        QModelIndex index = _header->index(i, 1);
        columnComboBox->addItem(_header->data(index).toString());
    }
    columnComboBox->setCurrentIndex(-1);
    templateFilterWidget = new TemplateFilterWidget;
    
    gridLayout->addWidget(columnComboBox, _row, 1);
    
    connect(columnComboBox, SIGNAL(activated(int)),
            this, SLOT(columnActivated(int)));
}
// ---------------------------------------------------------------------------


// ----------------------- columnActivated() ---------------------------------
void FilterWidget::columnActivated(int column)
{
    if(column == -1) {
        return;
    }
    
        // sprawdzaj typ 
    QModelIndex index = _header->index(column, 2);
    if(_header->data(index).toString() == "relatedString") {
        delete templateFilterWidget;
            // utwórz liste danych do comboBox 
        QSqlTableModel *table = new QSqlTableModel;
        index = _header->index(column, 3);
        table->setTable(_header->data(index).toString());
        table->select();
        QStringList *dataList = new QStringList;
        for(int i = 0; i < table->rowCount(); i++) {
            QModelIndex tableIndex = table->index(i, 1);
            dataList->append(table->data(tableIndex).toString());
        }
        templateFilterWidget = new StringFilterWidget(dataList, column);
        gridLayout->addWidget(templateFilterWidget, _row, 2);
        connect(templateFilterWidget, SIGNAL(activated(bool)),
                this, SLOT(setActive(bool)));
    }
    if(_header->data(index).toString() == "uint") {
        delete templateFilterWidget;
        templateFilterWidget = new UIntFilterWidget(column);
        gridLayout->addWidget(templateFilterWidget, _row, 2, 1, 2);
        connect(templateFilterWidget, SIGNAL(activated(bool)),
                this, SLOT(setActive(bool)));
    }    
    if(_header->data(index).toString() == "float") {
        delete templateFilterWidget;
        templateFilterWidget = new DoubleFilterWidget(column);
        gridLayout->addWidget(templateFilterWidget, _row, 2, 1, 2);
        connect(templateFilterWidget, SIGNAL(activated(bool)),
                this, SLOT(setActive(bool)));
    }    
    if(_header->data(index).toString() == "date") {
        delete templateFilterWidget;
        templateFilterWidget = new DateFilterWidget(column);
        gridLayout->addWidget(templateFilterWidget, _row, 2, 1, 2);
        connect(templateFilterWidget, SIGNAL(activated(bool)),
                this, SLOT(setActive(bool)));
    }
    if(_header->data(index).toString() == "limitedString") {
        delete templateFilterWidget;
        templateFilterWidget = new LimitedStringFilterWidget(column);
        gridLayout->addWidget(templateFilterWidget, _row, 2);
        connect(templateFilterWidget, SIGNAL(activated(bool)),
                this, SLOT(setActive(bool)));
    }
}
// ---------------------------------------------------------------------------


// ---------------------- filterModel() --------------------------------------
FilterModel * FilterWidget::filterModel()
{
    return templateFilterWidget->filterModel();
}
// ---------------------------------------------------------------------------





// ===========================================================================
//                            StringFilterWidget
// ===========================================================================


// -------------------------- StringFilterWidget() ---------------------------
StringFilterWidget::StringFilterWidget(QStringList *dataList,
                                       int column,
                                       QWidget *parent,
                                       Qt::WFlags f)
    : TemplateFilterWidget(parent, f)
{
    _column = column;
    setDataList(dataList);
    dataComboBox = new QComboBox;
    dataComboBox->addItems(_dataList);
    dataComboBox->setCurrentIndex(-1);
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(dataComboBox);
    setLayout(layout);
        
    connect(dataComboBox, SIGNAL(activated(int)),
            this, SLOT(checkActive(int)));
}
// ---------------------------------------------------------------------------


// ------------------------- setDataList() -----------------------------------
void StringFilterWidget::setDataList(const QStringList *dataList)
{
    _dataList.clear();
    
        // pierwszy elemnt to treść nagłówka a drugi to typ
        // dlatego dwa pierwsze elementy pomijamy
    for(int i = 0; i < dataList->size(); i++) {
        _dataList << dataList->at(i);
    }
}
// ---------------------------------------------------------------------------


// ---------------------------- filterModel() --------------------------------
FilterModel * StringFilterWidget::filterModel()
{
    if(dataComboBox->currentIndex() == -1) {
        return NULL;
    }
    
    RegExpSortFilterProxyModel *filter = new RegExpSortFilterProxyModel;
    filter->setFilterKeyColumn(_column);
    QString string = _dataList.at(dataComboBox->currentIndex());
    QRegExp regExp(string, Qt::CaseInsensitive);
    filter->setFilterRegExp(regExp);
    
    return filter;
}
// ---------------------------------------------------------------------------


// ------------------------ checkActive() ------------------------------------
void StringFilterWidget::checkActive(int index)
{
    if(index == -1) {
        emit activated(false);
    } else {
        emit activated(true);
    }
}
// ---------------------------------------------------------------------------






// ===========================================================================
//                      LimitedStringFilterWidget
// ===========================================================================


// ----------------------- LimitedStringFilterWidget() -----------------------
LimitedStringFilterWidget::LimitedStringFilterWidget(int column,
        QWidget *parent, Qt::WFlags f)
    : TemplateFilterWidget(parent, f)
{
    _column = column;
    
    lineEdit = new QLineEdit;
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(lineEdit);
    setLayout(layout);
        
    connect(lineEdit, SIGNAL(editingFinished()), this, SLOT(checkActive()));
}
// ---------------------------------------------------------------------------


// ---------------------------- filterModel() --------------------------------
FilterModel * LimitedStringFilterWidget::filterModel()
{
    RegExpSortFilterProxyModel *filter = new RegExpSortFilterProxyModel;
    filter->setFilterKeyColumn(_column);
    QRegExp regExp(lineEdit->text(), Qt::CaseInsensitive);
    filter->setFilterRegExp(regExp);
    
    return filter;
}
// ---------------------------------------------------------------------------


// -------------------------- checkActive() ----------------------------------
void LimitedStringFilterWidget::checkActive()
{
    if(lineEdit->text().size() != 0) {
        emit activated(true);
    } else {
        emit activated(false);
    }
}
// ---------------------------------------------------------------------------






// ===========================================================================
//                                UIntFilterWidget 
// ===========================================================================


// ----------------------- UIntFilterWidget() --------------------------------
UIntFilterWidget::UIntFilterWidget(int column,
                                   QWidget *parent,
                                   Qt::WFlags f)
    : TemplateFilterWidget(parent, f)
{
    _column = column;
    
    fromLabel = new QLabel(QString::fromUtf8("Od:"));
    toLabel = new QLabel(QString::fromUtf8("Do:"));
    lowerBoundEdit = new QLineEdit;
    upperBoundEdit = new QLineEdit;
    QIntValidator *lowerBoundValidator = new QIntValidator(this);
    lowerBoundValidator->setBottom(0);
    QIntValidator *upperBoundValidator = new QIntValidator(this);
    upperBoundValidator->setBottom(0);
    lowerBoundEdit->setValidator(lowerBoundValidator);
    upperBoundEdit->setValidator(upperBoundValidator);
    
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(fromLabel);
    layout->addWidget(lowerBoundEdit);
    layout->addWidget(toLabel);
    layout->addWidget(upperBoundEdit);
    
    setLayout(layout);
    
    connect(lowerBoundEdit, SIGNAL(editingFinished()),
            this, SLOT(checkActive()));
    connect(upperBoundEdit, SIGNAL(editingFinished()),
            this, SLOT(checkActive()));
}
// ---------------------------------------------------------------------------


// -------------------------- filterModel() ----------------------------------
FilterModel * UIntFilterWidget::filterModel()
{
    int lowerBound;
    int upperBound;
    bool ok = false;
    
    lowerBound = lowerBoundEdit->text().toInt(&ok);
    if(!ok) {
        return NULL;
    }
    upperBound = upperBoundEdit->text().toInt(&ok);
    if(!ok) {
        return NULL;
    }
    
    DoubleSortFilterProxyModel *filter = new DoubleSortFilterProxyModel;
    filter->setFilterKeyColumn(_column);
    filter->setLowerBound((double)lowerBound);
    filter->setUpperBound((double)upperBound);
    
    return filter;
}
// ---------------------------------------------------------------------------


// ------------------------- checkActive() -----------------------------------
void UIntFilterWidget::checkActive()
{
    bool lowerOK;
    bool upperOK;
    
    lowerBoundEdit->text().toInt(&lowerOK);
    upperBoundEdit->text().toInt(&upperOK);
    if(lowerOK && upperOK) {
        emit activated(true);
    } else {
        emit activated(false);
    }
}
// ---------------------------------------------------------------------------






// ===========================================================================
//                              DoubleFilterWidget 
// ===========================================================================


// --------------------- DoubleFilterWidget() --------------------------------
DoubleFilterWidget::DoubleFilterWidget(int column,
                                       QWidget *parent,
                                       Qt::WFlags f)
    : TemplateFilterWidget(parent, f)
{
    _column = column;
    
    fromLabel = new QLabel(QString::fromUtf8("Od:"));
    toLabel = new QLabel(QString::fromUtf8("Do:"));
    lowerBoundEdit = new QLineEdit;
    upperBoundEdit = new QLineEdit;
    QDoubleValidator *lowerBoundValidator = new QDoubleValidator(this);
    lowerBoundValidator->setBottom(0);
    QDoubleValidator *upperBoundValidator = new QDoubleValidator(this);
    upperBoundValidator->setBottom(0);
    lowerBoundEdit->setValidator(lowerBoundValidator);
    upperBoundEdit->setValidator(upperBoundValidator);
    
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(fromLabel);
    layout->addWidget(lowerBoundEdit);
    layout->addWidget(toLabel);
    layout->addWidget(upperBoundEdit);
    
    setLayout(layout);
    
    connect(lowerBoundEdit, SIGNAL(editingFinished()),
            this, SLOT(checkActive()));
    connect(upperBoundEdit, SIGNAL(editingFinished()),
            this, SLOT(checkActive()));
}
// ---------------------------------------------------------------------------


// -------------------------- filterModel() ----------------------------------
FilterModel * DoubleFilterWidget::filterModel()
{
    double lowerBound;
    double upperBound;
    bool ok = false;
    
    lowerBound = lowerBoundEdit->text().toDouble(&ok);
    if(!ok) {
        return NULL;
    }
    upperBound = upperBoundEdit->text().toDouble(&ok);
    if(!ok) {
        return NULL;
    }
    
    DoubleSortFilterProxyModel *filter = new DoubleSortFilterProxyModel;
    filter->setFilterKeyColumn(_column);
    filter->setLowerBound(lowerBound);
    filter->setUpperBound(upperBound);
    
    return filter;
}
// ---------------------------------------------------------------------------


// ------------------------- checkActive() -----------------------------------
void DoubleFilterWidget::checkActive()
{
    bool lowerOK;
    bool upperOK;
    
    lowerBoundEdit->text().toDouble(&lowerOK);
    upperBoundEdit->text().toDouble(&upperOK);
    if(lowerOK && upperOK) {
        emit activated(true);
    } else {
        emit activated(false);
    }
}
// ---------------------------------------------------------------------------






// ===========================================================================
//                              DateFilterWidget
// ===========================================================================


// ----------------------- DateFilterWidget() --------------------------------
DateFilterWidget::DateFilterWidget(int column,
                                       QWidget *parent,
                                       Qt::WFlags f)
    : TemplateFilterWidget(parent, f)
{
    _column = column;
    
    fromLabel = new QLabel(QString::fromUtf8("Od:"));
    toLabel = new QLabel(QString::fromUtf8("Do:"));
    lowerBoundEdit = new QDateEdit(QDate::currentDate());
    upperBoundEdit = new QDateEdit(QDate::currentDate());
    lowerBoundEdit->setDate(QDate::currentDate());
    upperBoundEdit->setDate(QDate::currentDate());
    
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(fromLabel);
    layout->addWidget(lowerBoundEdit);
    layout->addWidget(toLabel);
    layout->addWidget(upperBoundEdit);
    
    setLayout(layout);
    
    connect(lowerBoundEdit, SIGNAL(dateChanged(const QDate &)),
            this, SLOT(checkActive(const QDate &)));
    connect(upperBoundEdit, SIGNAL(dateChanged(const QDate&)),
            this, SLOT(checkActive(const QDate &)));
}
// ---------------------------------------------------------------------------


// -------------------------- filterModel() ----------------------------------
FilterModel * DateFilterWidget::filterModel()
{
    QDate lowerBound;
    QDate upperBound;
    
    lowerBound = lowerBoundEdit->date();
    upperBound = upperBoundEdit->date();
    
    DateSortFilterProxyModel *filter = new DateSortFilterProxyModel;
    filter->setFilterKeyColumn(_column);
    filter->setLowerBound(lowerBound);
    filter->setUpperBound(upperBound);
    
    return filter;
}
// ---------------------------------------------------------------------------


// ------------------------- checkActive() -----------------------------------
void DateFilterWidget::checkActive(const QDate &)
{
    emit activated(true);
}
// ---------------------------------------------------------------------------






